package cliente.mediador;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import servidor.dominio.*;
import servidor.principal.assembler.*;

import cliente.ClienteConection;
import cliente.Funciones;
import cliente.gui.*;
import comun.dto.*;
import comun.iControl.*;
import report.*;




//agregar el tema de si va en vacaciones o no..
public class MediadorReciboDeSueldo implements ActionListener {
	
	private GUIReciboDeSueldo guiRecibo=null;
	private GUILiquidar guiLiquidar=null;
	public IControlReciboDeSueldo controlRecibo;
	public IControlEmpleado controlEmpleado; 
	public IControlCliente controlCliente; 
	private Funciones fun;
	private Double subTotalImporte=(double) 0;
	private Double subTotalDescuento=(double) 0; 
	private Double subTotalRemunerativo=(double) 0;
	private Double subTotalNoRemunerativo=(double) 0;
	private Double neto=(double) 0;
	private ViewReport report=null;
	
	public MediadorReciboDeSueldo(String cuil, String cuit, int anio, String mes) throws Exception {
		ClienteConection empleadoConexion = new ClienteConection();
		try{ 
			empleadoConexion.iniciar(); 
		}catch(Exception ex){
			ex.printStackTrace();
		}
		this.controlEmpleado=empleadoConexion.getIControlEmpleado();
		this.controlCliente=empleadoConexion.getIControlCliente();
		this.controlRecibo=empleadoConexion.getIControlRecibo();
		guiRecibo= new GUIReciboDeSueldo();
		guiLiquidar=new GUILiquidar();
		fun=new Funciones();
		//llama a la funcion que retorne el empleado para luego setear en la interface los valores de dicho empleado
		Vector<EmpleadoDTO> empleado=controlEmpleado.getEmpleadosCuil(cuil);
		int ant=fun.antiguedad(empleado.get(0).getFechaIngreso());
		String antiguedad=String.valueOf(ant);
		guiRecibo.getCuil().setText(cuil);
	    guiRecibo.getEmpleado().setText(empleado.get(0).getNombre()+" "+empleado.get(0).getApellido());
	    guiRecibo.getFechaIngreso().setText(empleado.get(0).getFechaIngreso());
	    guiRecibo.getCategoria().setText(empleado.get(0).getCategoria().getNombre());
	    guiRecibo.getMesLiquidar().setText(mes.toUpperCase()+"-"+anio);
	    guiRecibo.getAntiguedad().setText(antiguedad);	    
	    guiRecibo.getBasico().setText(empleado.get(0).getCategoria().getSalario().toString());
	    guiRecibo.getCajaDeAhorro().setText(empleado.get(0).getNroDeCuenta());
	    guiRecibo.getBanco().setText(empleado.get(0).getBanco());
	    guiRecibo.getSucursal().setText(empleado.get(0).getNroDeSucursal()); 
	    guiRecibo.getPerteneciente().setText(empleado.get(0).getNombre()+" "+ empleado.get(0).getApellido());
	    //total por antiguedad y presentismo mejorar para que inserte el porcentaje
	    Double basico=empleado.get(0).getCategoria().getSalario();
	    Double totalAnt=totalPorAntiguedad(basico,Integer.parseInt(antiguedad),1);
	    guiRecibo.getTotalAntiguedad().setText(totalAnt.toString());	    	    
	    //llamada a funcion que calcula el subtotal de descuentos, remunerativo y no remunerativos
	    subTotalNoRemunerativo=this.subTotaleNoRemunerativo(empleado.get(0));
	    //subTotalBasico
	    //AGREGAR EN LA INTERFACE GRAFICA SI LIQUIDA VACACIONES, SI VA AGUINALDO O NO Y SI PONE VACACIONES(remunerativa o no) PEDIR CANT DIAS.
	    boolean vacaciones=false;//obtener de la interface seria guiLiquidar.getVacaciones 
	    boolean aguinaldo=false;//obtener de lainterface.. guiLiquidar.getAguinaldo
	    int diasVac=0;
	    double vacRem=0;
	    double vacNoRem=0;
	    double sac=0;//obtener el sac, es el 50% del mejor sueldo cobrado en el semestre
	    int diasRest=fun.cantDiasDelMes((guiLiquidar.getMes().getMonth()), anio)-diasVac;
	    if (true/*obtenerElValorDeVacacionesDeLaInterface*/){//ver si es  vacaciones remunerativa o no
	    	if(true/*VacacionesRemunerativa*/){
	    		vacRem=(basico/25)*diasVac;//concepto vacaciones agregar a la tabla...	
	    		basico=(basico/30)*diasRest;
	    	}else{
	    		vacNoRem=(((subTotalNoRemunerativo/25)*diasVac)+((subTotalNoRemunerativo/30)*diasRest))-subTotalNoRemunerativo;	
	    		
	    	}	    		    	
	    }
	    Double subTotalBasico=subTotalBasico(basico,totalAnt,mes,diasRest,sac,aguinaldo,vacaciones);//preguntar si no hace falta calcular el basico
	    																						//haciendo calculo con el presentismo o el presentismo lo
	    																						//calculo al ultimo y el basico con los remunerativo calculo los porcentajes	    	    
	    subTotalRemunerativo=subTotalRemunerativo(empleado.get(0),subTotalBasico,subTotalNoRemunerativo);
	    //
	    Double presentismo=presentismoRemun(basico,Double.parseDouble(antiguedad),8.33,vacRem,subTotalRemunerativo,vacaciones);
	    guiRecibo.getPresentismo().setText(presentismo.toString());			
	    double presentismoNoRem=presentismoNoRemun(8.33,subTotalNoRemunerativo);//agregar en la interface ver la hoja para el calculo..
	    subTotalBasico=subTotalBasico+presentismo+presentismoNoRem;
	    subTotalDescuento=subTotalDescuento(empleado.get(0),subTotalBasico,subTotalNoRemunerativo);
	    guiRecibo.getSubTotalBasico().setText(subTotalBasico.toString());
	    //
	    neto=(subTotalBasico+subTotalRemunerativo+subTotalNoRemunerativo)-subTotalDescuento;
	    //seteo en la tabla de la interface los resultados obtenidos
	    guiRecibo.getSubTotalDescuentos().setText(subTotalDescuento.toString());
	    guiRecibo.getSubTotalNoRemunerativo().setText(subTotalNoRemunerativo.toString());
	    guiRecibo.getSubTotaRemunerativo().setText(subTotalRemunerativo.toString());	   
	    guiRecibo.getNeto().setText(neto.toString());
	    guiRecibo.getNetoBanco().setText(neto.toString());
	    //llamo a getclientes para obtener la empresa a la que pertenece el empleado y setear los valores en la interface
	    Vector<ClienteDTO> empresa=controlCliente.getClientesCuit(cuit);
	    guiRecibo.getCuit().setText(cuit);
	    guiRecibo.getEmpresa().setText(empresa.get(0).getNombre());
	     
	    //seteo en la tabla de la interface los conceptos con sus respectivos valores y su respectivo tipo(descuento, remunerativo, no remunerativo)
	    guiRecibo.setTablaConceptos(empleado.get(0),subTotalBasico,subTotalNoRemunerativo);
	    //
	   	guiRecibo.setActionListeners(this);
		show();
		
	}
	
	
	  private void show() {  	    	
	        guiRecibo.show();
	    }
	  
	  
	  //subTotalDescuento
	  //SI SE MODIFICA LO DE REMUNERATIVO EN LA INTERFACE GRAFICA POR SI O NO SE DEBE
	  //CAMBIAR EL TRUE Y FALSE POR SI O NO RESPECTIVAMENTE
	  public double subTotalDescuento(EmpleadoDTO empleado, Double subTotalBasico,Double subTotalNoRemunerativo){
		  Set conceptos=empleado.getConceptos();
			Iterator<Concepto> iter=conceptos.iterator();
			//int i=0;
			
			while (iter.hasNext()){
				Concepto con = iter.next();
					if (con.getRemunerativo().equals("true")){
						if(con.getTipo().equals("Descuento")){
							if (con.getImporte()==0.0){
								subTotalDescuento=(con.getPorcentaje()*subTotalBasico) /100+ subTotalDescuento;
							}else{
								subTotalDescuento=con.getImporte()+ subTotalDescuento;
							}
						}
					}else{
						if(con.getTipo().equals("Descuento")){
							if (con.getImporte()==0.0){
								subTotalDescuento=(con.getPorcentaje()*subTotalNoRemunerativo)/100+ subTotalDescuento;
							
							}else{
							
								subTotalDescuento=con.getImporte()+ subTotalDescuento;
							}
						}
					}
				}	
			return subTotalDescuento;
		  	}
		  
	  
	  //funcion qu calcula los subtotales remunerativos y Descuentos
	  public double subTotalRemunerativo(EmpleadoDTO empleado, Double subTotalBasico,Double subTotalNoRemunerativo){
	  Set conceptos=empleado.getConceptos();
		Iterator<Concepto> iter=conceptos.iterator();
		//int i=0;
		
		while (iter.hasNext()){
			Concepto con = iter.next();
			if (con.getTipo().equalsIgnoreCase("HABER")){
				if(con.getRemunerativo().equalsIgnoreCase("true")){
					if (con.getImporte()==0.0){
						subTotalRemunerativo=(con.getPorcentaje()*subTotalBasico)/100+subTotalRemunerativo;
					}else{
						subTotalRemunerativo=con.getImporte()+subTotalRemunerativo;
					}
				}
			}	
		}		
		return subTotalRemunerativo;
	  }
	  
	  
	  
	  
	  
	  
	//funcion qu calcula los subtotales remunerativos y Descuentos
	  public void subTotales(EmpleadoDTO empleado, Double subTotalBasico,Double subTotalNoRemunerativo){
	  Set conceptos=empleado.getConceptos();
		Iterator<Concepto> iter=conceptos.iterator();
		//int i=0;
		
		while (iter.hasNext()){
			Concepto con = iter.next();
			if (con.getTipo().equalsIgnoreCase("HABER")){
				if(con.getRemunerativo().equalsIgnoreCase("true")){
					if (con.getImporte()==0.0){
						subTotalRemunerativo=(con.getPorcentaje()*subTotalBasico)/100+subTotalRemunerativo;
					}else{
						subTotalRemunerativo=con.getImporte()+subTotalRemunerativo;
					}
				}
			}
			else{
				if (con.getRemunerativo().equals("true")){
					if (con.getImporte()==0.0){
						subTotalDescuento=(con.getPorcentaje()*subTotalBasico) /100+ subTotalDescuento;
					}else{
						subTotalDescuento=con.getImporte()+ subTotalDescuento;
					}
				}else{
					if (con.getImporte()==0.0){
						subTotalDescuento=(con.getPorcentaje()*subTotalNoRemunerativo)/100+ subTotalDescuento;
						
					}else{
						
						subTotalDescuento=con.getImporte()+ subTotalDescuento;
					}
				}
			}	
		}		
	  	}
	  
	
	  // funcion que calcula el subTotal de NoRemunerativos
	  public Double subTotaleNoRemunerativo(EmpleadoDTO empleado){
		  Set conceptos=empleado.getConceptos();
			Iterator<Concepto> iter=conceptos.iterator();
			//int i=0;
			
			while (iter.hasNext()){
				Concepto con = iter.next();
				if (con.getTipo().equalsIgnoreCase("HABER")){
					if(con.getRemunerativo().equalsIgnoreCase("false")){
						subTotalNoRemunerativo=con.getImporte()+subTotalNoRemunerativo;
					}
				}	
			}		
			return subTotalNoRemunerativo;
		  	}
	  
	  
	  
	  
	  public double subTotalBasico(double basico, double antiguedad,String mes, int diasRest, double sac,boolean aguinaldo,boolean vacaciones){
		//  boolean aguinaldo=false;
		 // boolean vacaciones=false; //basico + presentismo/25 * dias de vacaciones. //vacaciones remunerativas
		  //basico+presentismo/30* los dias que faltan de trabajo// sueldo
		  //sac (pasado comp parametro)es el 50% del mejor sueldo cobrado en el semestre;
		  //obtener bien el basico a partir de la categoria.
		  //voy a tener que agregar dos campos mas el de aguinaldo o el de vacaciones o ambos en el recibo...
		  if (vacaciones && aguinaldo){
			  // este va a ser lo que va a ir en el campo sueldo basico
			  return ((basico/30)* diasRest)+sac; 	
		  }
		  else if(vacaciones && (!aguinaldo)){
			  return (basico/30)* diasRest;
		  }
		  else if (aguinaldo && (!vacaciones)){
			  return basico+antiguedad+sac;
		  }
		  else{
			  return basico+antiguedad;
		  }
	  }
	  
	  public double totalPorAntiguedad(double basico,int anos, int porcentaje){
		  return (((double)porcentaje/(double)100)*basico)*anos;
	  }
	  
	  //hay dos presentismos uno remunerarivo y el otro no remunerativo
	  //el primero se cacula a partir del sueldo basico, antiguedad,y conceptos remunerativo
	  //el otro a partir de los conceptos no remunerativos
	  public double presentismoRemun(double basico, double antiguedad, double porcentaje,double vac,double subTotalRemunerativos,boolean vacaciones){
		 if (vacaciones){
			 return (basico+vac+antiguedad+subTotalRemunerativos)*(porcentaje/100);
		 }else{
		  return (antiguedad+basico+subTotalRemunerativos)*(porcentaje/100);
		 }
	  }
	  
	  public double presentismoNoRemun(double porcentaje,double subTotalNoRemunerativo){
				 return (subTotalNoRemunerativo)*(porcentaje/100);
		  }
	  
	  public void actionPerformed(ActionEvent e) {
			Object source = e.getSource();
			try{
				if (source==guiRecibo.getGuardar()){
					Double subTotalBasico=Double.parseDouble(guiRecibo.getSubTotalBasico().getText());
					Double subTotalNoRemunerativo=Double.parseDouble(guiRecibo.getSubTotalNoRemunerativo().getText());
					Double subTotalRemunerativo=Double.parseDouble(guiRecibo.getSubTotaRemunerativo().getText());
					Double subTotalDescuento=Double.parseDouble(guiRecibo.getSubTotalDescuentos().getText());
					String mesLiquidar=guiRecibo.getMesLiquidar().getText();
					Double total=Double.parseDouble(guiRecibo.getNeto().getText());
					//a partir de estos datos obtengo despues la Empresa Empleado-> Conceptos y Categoria..
					String cuitEmpresa=guiRecibo.getCuit().getText();
					String cuil=guiRecibo.getCuil().getText();
					String categoria=guiRecibo.getCategoria().getText();
					Vector<ClienteDTO> empresa=controlCliente.getClientesCuit(cuitEmpresa);
					Vector<EmpleadoDTO> empl=controlEmpleado.getEmpleadosCuil(cuil);
					ClienteDTO cliente=empresa.get(0);
					Cliente emp=ClienteAssembler.getCliente(cliente);
					EmpleadoDTO empleado=empl.get(0);
					Empleado emplead=EmpleadoAssembler.getEmpleado(empleado);
					Categoria cat=empl.get(0).getCategoria();
					Set conceptos=empl.get(0).getConceptos();
					
					String cuilEmpl=emplead.getCuil();
					//VER COMO SOLUCIONAR EL PROBLEMA QUE CARGA EMPELADOS Y CLIENTES NUEVAMENTE..
					ReciboDeSueldoDTO rDTO = new ReciboDeSueldoDTO();
					//al setear los conceptos y la categoria tmb agregan un nuevo empleado
					//rDTO.setCategoria(cat);
					//rDTO.setConceptos(conceptos);
					//AL SETEAR AGREGA DOS EMPLEADOS Y DOS CLIENTES MAS.. SOLUCIONAR...
					//rDTO.setEmpleado(emplead);
					//rDTO.setEmpresa(emp);
					rDTO.setMesLiquidar(mesLiquidar);
					rDTO.setSubTotalBasico(subTotalBasico);
					rDTO.setSubTotalDescuentos(subTotalDescuento);
					rDTO.setSubTotalNoRemunerativo(subTotalNoRemunerativo);
					rDTO.setSubTotalRemunerativos(subTotalRemunerativo);
					rDTO.setTotal(total);
					//falta hacer el contro para ver si existe el mes y el empleado ya cargado...
					//arreglar aca porque carga empleado de vuelta y mas clienets tmb...
					/*if((controlRecibo.existeEmpleado(empleado)) && (controlRecibo.existeMes(mesLiquidar))){
						JOptionPane.showMessageDialog(new JFrame(),"Recibo ya existente !!!","INFORME DE RECIBO",JOptionPane.INFORMATION_MESSAGE);
					}*/
				//el tema esta en el add cuando le paso el recibo como parametro..
					controlRecibo.addReciboDeSueldoDTO(rDTO,cuitEmpresa,categoria,cuilEmpl,conceptos);
					
					
				}else if(source==guiRecibo.getImprimir()){
					//dentro del mediador cuando presione el boton imprimir hacer que llame al ViewReport.	
					 /*PrinterJob job = PrinterJob.getPrinterJob();
		                job.setPrintable(guiRecibo);
		                //--------------------------------------------
		                boolean aceptar_impresion =job.printDialog();
		                 if(aceptar_impresion)
		                    job.print();
		                //---------------------------------------------*/
						report=new ViewReport();
						report.viewReportLiquidacion();
						
				}else if (source==guiRecibo.getSalir()){
					guiRecibo.dispose();
				}
			}catch(Exception p){
				System.out.println("Error en MediadorRecibo:");
				System.err.println("Caught Exception: " + p.getMessage());
			}
	  
	  }	  
}




